package com.juyu.miliao.authentication;

import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.hibernate.validator.HibernateValidator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
import org.springframework.session.web.http.HttpSessionIdResolver;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import com.juyu.miliao.authentication.config.SpringContextUtil;

@SpringBootApplication
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 5*24*60*60) //单位秒(5天)
@EnableCaching
public class SocialAuthenticationApplication {

	public static void main(String[] args) {
		ApplicationContext socialApiApplication = SpringApplication.run(SocialAuthenticationApplication.class, args);
		SpringContextUtil.setApplicationContext(socialApiApplication);
	}
	@Bean
	public HttpSessionIdResolver httpSessionIdResolver() {
		return HeaderHttpSessionIdResolver.xAuthToken(); 
	}
	
	@Bean
	public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
        return new MappingJackson2HttpMessageConverter(objectMapper());
	}
	
	@Bean
	public ObjectMapper objectMapper(){
		ObjectMapper objectMapper = new ObjectMapper()
        		.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX)
        		.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN)
				.registerModule(new ParameterNamesModule())
				.registerModule(new Jdk8Module())
				.registerModule(new JavaTimeModule())
				.setSerializationInclusion(Include.NON_EMPTY);
		return objectMapper;
	}
	
	@Bean
	public LocalValidatorFactoryBean validator() {
		LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
		localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
		Map<String, String> validationProperties = new HashMap<>();
		validationProperties.put("hibernate.validator.fail_fast", "true");
		localValidatorFactoryBean.setValidationPropertyMap(validationProperties);
		return localValidatorFactoryBean;
	}

	@Bean public CacheManager cacheManager(RedisConnectionFactory factory) {
		// 生成一个默认配置，通过config对象即可对缓存进行自定义配置
		RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
		// 设置一个初始化的缓存空间set集合
		Set<String> cacheNames =  new HashSet<>();
		cacheNames.add("timeout-cache-qqDTOCache");
		cacheNames.add("timeout-cache-authentication-appKeyCache");
		// 对每个缓存空间应用不同的配置
		Map<String, RedisCacheConfiguration> configMap = new HashMap<>();

		configMap.put("timeout-cache-qqDTOCache",
				config.entryTtl(Duration.ofMinutes(10)));
		configMap.put("timeout-cache-authentication-appKeyCache",
				config.entryTtl(Duration.ofMinutes(10)));
		RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
				.initialCacheNames(cacheNames)
				.withInitialCacheConfigurations(configMap)
				.build();
		return cacheManager;
	}
}
